package cn.byapps.service.impl;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import cn.byapps.core.utils.DecryptUtil;
import cn.byapps.dao.UploadFileDao;
import cn.byapps.dao.UserDao;
import cn.byapps.entity.UploadFile;
import cn.byapps.entity.User;
import cn.byapps.service.UserService;

@Service
@Transactional(readOnly = true)
public class UserServiceImpl implements UserService {

	@Resource
	private UserDao userDao;
	@Resource
	private UploadFileDao uploadFileDao;
	@Value("${upload}")
	private String upLoadPath;

	@Override
	public User login(String username, String password) {

		Map<String, Object> searchParams = new HashMap<String, Object>();
		searchParams.put("loginName", username);
		searchParams.put("pwd", password);
		searchParams.put("valid", 1);
		List<User> us = userDao.findAll(searchParams);
		if (us != null && us.size() == 1) {
			return us.get(0);
		}
		return null;
	}

	@Override
	public User get(String token) {
		return userDao.get(Integer.parseInt(token));
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	@Override
	public Boolean delete(User user) {
		user = userDao.get(user.getId());
		user.setParent(null);
		return true;
		// 1-24 要求只删除关系
//		if (user != null && user.getChildren().isEmpty()) {
//			if (user.getCoupleId() != null) {
//				User u = userDao.get(user.getCoupleId());
//				if (u != null) {
//					u.setCoupleId(null);
//					u.setCoupleName(null);
//				}
//			}
//			userDao.delete(user);
//			return Boolean.TRUE;
//		}
//		return Boolean.FALSE;
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	@Override
	// 物理删除为 TRUE 逻辑删除为FASLE
	public boolean deleteByAdmin(User user) {
		user = userDao.get(user.getId());
		// 没有后代以及没有文件才能删除
		if (user != null) {
			if (user.getChildren().isEmpty() && user.getFiles().isEmpty()) {
				if (user.getCoupleId() != null) {
					User u = userDao.get(user.getCoupleId());
					if (u != null) {
						u.setCoupleId(null);
						u.setCoupleName(null);
					}
				}
				userDao.delete(user);
				return Boolean.TRUE;
			} else {
				user.setValid(0);
				return Boolean.FALSE;
			}
		}
		return Boolean.TRUE;
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	@Override
	public boolean startByAdmin(User user) {
		user = userDao.get(user.getId());
		// 没有后代以及没有文件才能删除
		if (user != null) {
			user.setValid(1);
			return Boolean.TRUE;
		}
		return Boolean.FALSE;
	}

	@Override
	public User findByLoginName(String loginName) {
		Map<String, Object> searchParams = new HashMap<String, Object>();
		searchParams.put("loginName", loginName);
		List<User> us = userDao.findAll(searchParams);
		if (us != null && us.size() == 1) {
			return us.get(0);
		}
		return null;
	}

	@Override
	public User getParent(String token) {
		User u = userDao.get(Integer.parseInt(token));
		User parent = null;
		while (u != null && (parent = u.getParent()) != null) {
			u = parent;
		}
		return u;
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	@Override
	public User save(User user) {
		userDao.add(user);
		return user;
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	@Override
	public User update(User user) {
		userDao.update(user);
		return user;
	}

	@Override
	public List<User> findAll() {
		return userDao.findAll();
	}

	@Override
	public List<User> findByName(String username) {
		Map<String, Object> searchParams = new HashMap<String, Object>();
		searchParams.put("name", "%" + username + "%");
		return userDao.findAll(searchParams);
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	@Override
	public boolean changePassword(User u, String pwd) {
		//System.out.println(pwd);
		u = userDao.get(u.getId());
		u.setPwd(DecryptUtil.MD5(u.getLoginName() + pwd));
		userDao.update(u);
		return true;
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	@Override
	public void uploadFile(User u, String name, String title, MultipartFile myfile) {
		if (myfile != null) {// 文件不为空
			String path = null;
			if (upLoadPath == null || upLoadPath.equals("")) {
				path = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()
						.getServletContext().getRealPath("/upload/");// 获取项目路径+upload目录
			} else {
				path = upLoadPath;
			}
			// 循环文件

			int hz = myfile.getOriginalFilename().lastIndexOf(".");// 最后一点，下标
			String newFileName = UUID.randomUUID() + (hz > 0 ? myfile.getOriginalFilename().substring(hz) : "");// uuid+文件名后缀
			File newFile = new File(path, newFileName);// 新文件实例
			// 物理保存文件
			try {
				myfile.transferTo(newFile);
			} catch (IllegalStateException | IOException e) {
				e.printStackTrace();
			}
			// 文件大小
			double fileSize = (double) myfile.getSize() / 1024 / 1024;
			BigDecimal b = new BigDecimal(fileSize);
			fileSize = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();// 四舍五入，保存两位小数
			uploadFileDao.add(new UploadFile(title, name, myfile.getOriginalFilename(), newFileName, fileSize, u));
		}
	}

	@Override
	public UploadFile getFile(String id) {
		return uploadFileDao.get(id);
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	@Override
	public void deleteFile(String id) {
		UploadFile u = new UploadFile();
		u.setId(id);
		uploadFileDao.delete(u);
	}

	@Override
	public User getById(Integer id) {
		return userDao.get(id);
	}

	@Override
	public boolean checkUser(User p, User me) {
		User u = userDao.get(p.getId());
		User parent = null;
		while (u != null && (parent = u.getParent()) != null) {
			u = parent;
		}
		if (u.getId().intValue() == me.getId().intValue())
			return true;
		else
			return check(u.getChildren(), me.getId());
		// while(u!=null && )

	}

	private boolean check(Set<User> u, int id) {
		for (User s : u) {
			//System.out.println(s.getName());
			if (s.getId().intValue() == id) {
				return true;
			} 
			boolean flag = false;
			if (s.getChildren().size() > 0) {
				flag =  check(s.getChildren(), id);
			} 
			if(flag)
				return true;
		}
		return false;
	}
}
